<template>
  <div class="rounded border border-solid border-color-split md:flex md:flex-row md:items-stretch md:h-120">
    <div class="md:w-3/5 flex flex-col">
      <div class="pt-2 px-2 sm:pt-4 sm:px-4 border-0 border-b border-color-split border-solid">
        <div class="pb-2 sm:pb-4">
          <a-input-search
            v-model:value="keyword"
            :placeholder="searchPlaceholder"
            size="small"
            class="!w-full"
            :allow-clear="true"
            :maxlength="32"
            @search="keywordSearch"
          >
            <template #enterButton>
              <a-button>
                <template #icon><Icon type="icon-sousuo" /></template>
              </a-button>
            </template>
          </a-input-search>
        </div>
      </div>
      <div class="flex-1 relative rounded overflow-auto p-4">
        <a-spin v-if="!loadingTree && innerTreeData && innerTreeData.length > 0" :spinning="loadingTree">
          <a-tree
            :checked-keys="treeCheckedKeys"
            :expanded-keys="treeExpandedKeys"
            checkable
            :tree-data="innerTreeData"
            @check="handleTreeCheck"
            @expand="treeExpand"
            @select="handleTreeSelect"
          >
          </a-tree>
        </a-spin>
        <div v-else class="h-full flex flex-col items-center justify-center">
          <sl-empty />
        </div>
      </div>
    </div>
    <div class="md:w-2/5 border-0 border-t md:border-t-0 md:border-l border-solid border-color-split flex flex-col">
      <div class="py-4.5 flex flex-row items-center pl-4 pr-4.5">
        <div class="flex-1">
          <span class="text-lg font-semibold text-color-header">{{ t("common.choosed") }}</span>
          <span class="text-color-secondary">({{ treeCheckedKeys.length }})</span>
        </div>
        <div v-if="canClearAll" class="text-red-400 cursor-pointer" @click="clearSelected">
          {{ t("common.clear") }}
        </div>
      </div>
      <div v-if="checkedTreeData.length > 0" class="flex-1 overflow-auto pl-4 pr-4.5">
        <a-tree :tree-data="checkedTreeData" :default-expand-all="true" :block-node="true" class="checked-tree">
          <template #title="{ data }">
            <div class="text-color-main flex-1">
              {{ data.title }}
            </div>
            <div v-if="isNodeCanRemove(data)">
              <a @click.stop="removeSelected(data)">{{ t("common.remove") }}</a>
            </div>
          </template>
        </a-tree>
      </div>
      <div v-else class="flex-1 flex items-center justify-center pb-10">
        <SlEmpty />
      </div>
    </div>
  </div>
</template>
<script setup lang="ts">
import { useI18n } from "/@/locales/useI18n";
import { nextTick, computed, ref, watch } from "vue";
import type { UserItem, OrgUserSearchModel } from "/@/api/aiot/organization/models";
import { useCURD } from "/@/hooks/useCURD";
import { RequestMethodEnum } from "/@/api/req/httpEnum";
import SlEmpty from "/@/components/SlEmpty.vue";
import type { UserSelectExpose } from "/@/types/components";
import SlTable from "/@/components/SlTable.vue";
import type { OrgUserTreeItem } from "/@/api/aiot/role/models";
import type { TreeProps } from "ant-design-vue";
import EllipsisText from "/@/components/common/EllipsisText.vue";
import type { BodyCellOptions } from "/@/types/antd";
import { useUserStore } from "/@/stores/aiot/user";
import { findParents, filterItemsByKeyword, loopItem } from "/@/utils/treeData";
import type { DataNode } from "ant-design-vue/es/tree";
import { rowProps } from "ant-design-vue/lib/grid/Row";
import { cloneDeep } from "lodash-es";

const ALL_KEY = "all";
const props = withDefaults(
  defineProps<{
    //所勾选的id数组 双向绑定
    value: string[];
    //已选不能再操作的id数组
    disabledValue?: string[];
    treeData: DataNode[];
    loadingTree?: boolean;
    searchPlaceholder: string;
  }>(),
  {}
);
const emits = defineEmits(["update:value"]);
const { t } = useI18n();
/**
 * search
 */
const keyword = ref("");
function keywordSearch() {}
/**
 * tree
 */
const innerTreeData = computed(() => {
  if (props.treeData.length > 0) {
    const filterData = filterItemsByKeyword<DataNode>(props.treeData, keyword.value);
    if (filterData.length === 0) return [];
    const data: DataNode[] = [
      {
        title: "全选",
        key: ALL_KEY,
        children: filterData,
      },
    ];
    loopItem<DataNode>(data, (item) => {
      if (props.disabledValue?.includes(item.key as string)) {
        item.disableCheckbox = true;
      } else {
        if (item.children && item.children.length > 0) {
          let isDisable = true;
          for (let i = 0; i < item.children.length; i++) {
            if (!props.disabledValue?.includes(item.children[i].key as string)) {
              isDisable = false;
              break;
            }
          }
          if (isDisable) {
            item.disableCheckbox = true;
            return;
          }
        }
        item.disableCheckbox = false;
      }
    });
    return data;
  }
  return [];
});
const treeCheckedKeys = ref<string[]>([]);
const treeExpandedKeys = ref<string[]>([ALL_KEY]);
//没有搜索的情况下的所有checkedKeys
let checkedKeysForAllNode: string[] = [];
const handleTreeCheck: TreeProps["onCheck"] = async (checkedKeys, { checked, node }) => {
  // console.log(e);
  // selectedData.value = checkedNodes.filter((el) => el.transfterable);
  if (keyword.value) {
    const curAllKeys: string[] = [];
    loopItem<DataNode>(innerTreeData.value, (item) => {
      curAllKeys.push(item.key as string);
    });
    const unCheckedKeys: string[] = [];
    curAllKeys.forEach((key) => {
      if (!(checkedKeys as string[]).includes(key)) {
        unCheckedKeys.push(key);
      }
    });
    for (let i = checkedKeysForAllNode.length - 1; i >= 0; i--) {
      if (unCheckedKeys.includes(checkedKeysForAllNode[i])) {
        checkedKeysForAllNode.splice(i, 1);
      }
    }
    (checkedKeys as string[]).forEach((key) => {
      if (!checkedKeysForAllNode.includes(key)) {
        checkedKeysForAllNode.push(key);
      }
    });
    treeCheckedKeys.value = [...checkedKeysForAllNode];
  } else {
    treeCheckedKeys.value = checkedKeys as string[];
    checkedKeysForAllNode = [...treeCheckedKeys.value];
  }
  // console.log(checkedKeys);
};
const handleTreeSelect: TreeProps["onSelect"] = (_selectedKeys, e) => {};
const treeExpand: TreeProps["onExpand"] = (expandedKeys) => {
  treeExpandedKeys.value = expandedKeys as string[];
};
/**
 * 右边树
 */
//左边勾选的节点组成的树数据
const checkedTreeData = ref<DataNode[]>([]);
watch(treeCheckedKeys, (newCheckedKeys) => {
  const keys = [...newCheckedKeys];
  const index = keys.indexOf(ALL_KEY);
  if (index >= 0) {
    keys.splice(index, 1);
  }
  canUpdatePropValue && emits("update:value", keys);
  if (newCheckedKeys.length === 0) {
    checkedTreeData.value = [];
    return;
  }
  const copyData = cloneDeep<DataNode[]>(props.treeData);
  loopItem<DataNode>(
    copyData,
    (item, i, items) => {
      if (!newCheckedKeys.includes(item.key as string)) {
        if (!item.children || item.children.length === 0) {
          items.splice(i, 1);
        } else {
          let hasCheckNode = false;
          loopItem<DataNode>(item.children, (ch) => {
            if (newCheckedKeys.includes(ch.key as string)) {
              hasCheckNode = true;
              return false;
            }
          });
          if (!hasCheckNode) {
            items.splice(i, 1);
          }
        }
      }
    },
    null,
    true
  );
  checkedTreeData.value = copyData;
});
let canUpdatePropValue = true;
watch(
  () => props.value,
  (v) => {
    canUpdatePropValue = false;
    treeCheckedKeys.value = v;
    // handleAllNode();
    nextTick(() => {
      canUpdatePropValue = true;
    });
  },
  {
    immediate: true,
  }
);

function removeSelected(el: DataNode) {
  if (props.disabledValue?.includes(el.key as string)) return;
  const unCheckedKeys = [el.key];
  findParents<DataNode>(innerTreeData.value, el.key, "key", unCheckedKeys);
  const copyCheckedKeys = [...treeCheckedKeys.value];
  if (el.children && el.children.length > 0) {
    loopItem<DataNode>(el.children, (item) => {
      if (!props.disabledValue?.includes(item.key as string)) {
        unCheckedKeys.push(item.key);
      }
    });
  }
  for (let i = copyCheckedKeys.length - 1; i >= 0; i--) {
    if (unCheckedKeys.includes(copyCheckedKeys[i])) {
      copyCheckedKeys.splice(i, 1);
    }
  }
  treeCheckedKeys.value = copyCheckedKeys;
}
function clearSelected() {
  if (!props.disabledValue || props.disabledValue.length === 0) {
    treeCheckedKeys.value = [];
  } else {
    const newKeys: string[] = [];
    treeCheckedKeys.value.forEach((key) => {
      if (props.disabledValue?.includes(key)) {
        newKeys.push(key);
      }
    });
    treeCheckedKeys.value = newKeys;
    // loopItem<DataNode>(checkedTreeData.value, (item) => {
    //   removeSelected(item);
    // });
    // checkedTreeData.value.forEach((node) => {
    //   removeSelected(node);
    // });
  }
}
//是否有清空按钮，如果存在能移除的节点，则能清空
const canClearAll = computed(() => {
  //遍历所有叶子节点，存在能移除的则返回true
  let re = false;
  loopItem<DataNode>(checkedTreeData.value, (item) => {
    if ((!item.children || item.children.length === 0) && !props.disabledValue?.includes(item.key as string)) {
      re = true;
      return false;
    }
  });
  return re;
});
//处理"全选"节点状态
function handleAllNode() {
  let isAllCheck = true;
  props.treeData.forEach((item) => {
    if (!treeCheckedKeys.value.includes(item.key as string)) {
      isAllCheck = false;
    }
  });
  if (isAllCheck && !treeCheckedKeys.value.includes(ALL_KEY)) {
    treeCheckedKeys.value.push(ALL_KEY);
  }
}
//已选树中的节点是否能移除
function isNodeCanRemove(node: DataNode) {
  if (props.disabledValue?.includes(node.key as string)) return false;
  let re = true;
  if (node.children && node.children.length > 0) {
    //如果有一个孙子节点不能删 则自己也不能删
    loopItem<DataNode>(node.children, (item) => {
      if (props.disabledValue?.includes(item.key as string)) {
        re = false;
        return false;
      }
    });
  }
  return re;
}

defineExpose({
  getCheckedTreeData() {
    return checkedTreeData.value;
  },
});
</script>
<style lang="less">
.checked-tree {
  .ant-tree-node-content-wrapper {
    padding-right: 0;
  }
  .ant-tree-title {
    display: flex;
    flex-direction: row;
    align-items: center;
  }
}
</style>
